package com.lagou.rabbitmq.service;

import com.lagou.rabbitmq.bean.Order;
import com.lagou.rabbitmq.config.RabbitConfig;
import com.rabbitmq.client.Channel;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class OrderService {

    // 订单状态
    public static final String ORDER_STATUS_WAIT_PAY = "等待支付";
    public static final String ORDER_STATUS_PAY_SUC = "支付成功";
    public static final String ORDER_STATUS_EXPIRED = "订单超时";

    private static final AtomicInteger ORDER_ID = new AtomicInteger(100);
    private static final LinkedHashMap<Integer, Order> DB = new LinkedHashMap<>();

    @Autowired
    private AmqpTemplate rabbitTemplate;

    /**
     * 创建新订单
     *
     * @return
     */
    public Order createOrder() {
        // 创建新订单
        Order order = new Order();
        order.setId(ORDER_ID.incrementAndGet());
        order.setStatus(ORDER_STATUS_WAIT_PAY);
        order.setCreateTime(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        order.setExpireTimestamp(System.currentTimeMillis() + 10 * 1000L); // 支付超时10s
        DB.put(order.getId(), order);

        // 发送MQ，10s超时后进死信队列
        rabbitTemplate.convertAndSend(RabbitConfig.EX_PAY, RabbitConfig.RK_PAY, String.valueOf(order.getId()));

        return order;
    }

    /**
     * 订单列表
     *
     * @return
     */
    public List<Order> getOrders() {
        return DB.values().stream().collect(Collectors.toList());
    }

    /**
     * 支付订单
     *
     * @param orderId
     * @return
     */
    public String pay(Integer orderId) {
        Order order = DB.get(orderId);
        if (order.getStatus().equals(ORDER_STATUS_EXPIRED)
                || System.currentTimeMillis() > order.getExpireTimestamp()) {
            return "抱歉，订单已超时！";
        }
        order.setStatus(ORDER_STATUS_PAY_SUC);
        return "恭喜，订单支付成功！";
    }


    /**
     * 消费死信队列，监听超时订单MQ
     */
    @RabbitListener(queues = RabbitConfig.Q_PAY_EX, ackMode = "AUTO")
    public void expireOrder(Message message, Channel channel) throws IOException {
        String value = new String(message.getBody(), "UTF-8");
        System.out.println("=====> received orderId: " + value);

        // 如果该订单处于【等待支付】状态，则将订单状态更新为【订单超时】
        Integer orderId = Integer.valueOf(value);
        Order order = DB.get(orderId);
        if (order.getStatus().equals(ORDER_STATUS_WAIT_PAY)) {
            order.setStatus(ORDER_STATUS_EXPIRED);
            order.setExpiredTime(DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss"));
            System.out.println("=====> mark order expired! orderId: " + value);
        }
    }

}
